//
//  FileCleanVC.swift
//  ZJTools
//
//  Created by 万孟超 on 2023/10/19.
//

import Cocoa

class FileCleanVC: NSViewController {

    @IBOutlet var logTextView: NSTextView!
    @IBOutlet weak var projectPath: NSTextField!
    @IBOutlet weak var resultOutlineView: NSOutlineView!
    @IBOutlet weak var logCustomView: NSView!
    @IBOutlet weak var projectCustomView: NSView!
    
    @IBOutlet weak var outlineScrollView: NSScrollView!
    /// 搜索时，文件目录忽略列表
    let ignoreFloderArray = [".xctemplate", "XCFramework", ".xcframework", ".framework", ".xcassets", ".lproj", "Pods", ".xcodeproj", ".xcworkspace", ".gitattributes", ".gitignore", ".gitmodules", ".git"]
    
    /// 搜索时，文件目录忽略列表
    let ignoreFileArray = [".gitattributes", ".gitignore", ".gitmodules", ".DS_Store", "Podfile.lock", "Podfile", "LICENSE", "build-xcframework.sh", ".p12", ".md"]
    
    /// 保存路径集合
    var projectNotExportArray: [String] = []
    
    var searchFloderPath: String = ""
    
    var projectNotExportModel = FileCleanResult(path: "", floderList: [])
    
    var podsProject: Bool = false
    
    var logString: String = "" {
        didSet {
            Async(.main) {[self] in
                logTextView.textStorage?.setAttributedString(logString.attributedString)
                logTextView.scrollLineDown(nil)
            }
        }
    }
    
    /// 工程中导入的文件
    var projectUsedClassFile: [String] = []
    /// .xcodeProj的路径
    var projectNamePath: String = "" {
        didSet {
            Async(.global()) { [self] in
                Async(.main) {[self] in
                    logString += "\n" + "正在获取项目中导入的文件"
                }
                projectUsedClassFile = File.findProjectReferencedFiles(projectPath: projectNamePath)
                Async(.main) {[self] in
                    logString += "\n" + "项目中导入的文件获取成功"
                }
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        
        projectCustomView.wantsLayer = true
        projectCustomView.layer?.cornerRadius = 15
        projectCustomView.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.3).cgColor
        
        logCustomView.wantsLayer = true
        logCustomView.layer?.cornerRadius = 15
        logCustomView.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.3).cgColor
        
        outlineScrollView.wantsLayer = true
        outlineScrollView.layer?.cornerRadius = 15
        outlineScrollView.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.3).cgColor
    }
    
    @IBAction func developmentPodsChanged(_ sender: NSSwitch) {
        podsProject = sender.state == .on
        if !searchFloderPath.isEmpty {
            obtainPaths()
        }
    }
    
    @IBAction func chooseProjectPathAction(_ sender: NSButton) {
        File.finder(singleSelectBlock: {[weak self] path in
            self?.projectPath.stringValue = path
            self?.searchFloderPath = path
            self?.logString = "路径选择成功"
            self?.projectNotExportModel = FileCleanResult(path: path, floderList: [])
            self?.obtainPaths()
        })
    }
    @IBAction func showHelp(_ sender: NSButton) {
        let alertData = ["注意！！！：工具只是辅助检查，查找出的结果可能出错！！！",
                         "！！！不要盲目清理查询出来的文件，根据实际情况判断是否需要清理！！！",
                         "---------------------------------使用场景------------------------------",
                         "～协作开发合并代码后，删除的文件被重置回来～",
                         "～只删除了文件引用，没有删除文件实体～",
                         "---------------------------------查询原理------------------------------",
                         "1️⃣：根据xcodeproj中project.proj文件，解析出当前项目导入的文件",
                         "2️⃣：遍历当前选择的文件夹，如果导入的文件不包含当前文件，文件则没被导入",
                         "---------------------------------使用说明------------------------------",
                         "1️⃣.如果当前项目是以路径导入方式创建的项目，先将Development Pods打开",
                         "2️⃣.点击Brower，选择项目的路径（clone代码时创建的文件夹）",
                         "3️⃣.选择后右边窗口会给出进度日志，等待提示`项目中导入的文件获取成功`",
                         "4️⃣.点击Search按钮，右边窗口会提示当前打印出查询日志",
                         "5️⃣.查找完成后，下面结果窗口会给出查询结果",
                         "6️⃣.搜索结果展示的目录为相对路径",
                         "7️⃣.双击Cell的空白处，可在Finder中显示（文件和文件夹皆可以）"]
        NSPopover.showPopover(alertData, of: sender)
    }
    
    @IBAction func findNotExportFileAction(_ sender: NSButton) {
        Async(.global()) { [self] in
            if projectUsedClassFile.isEmpty  {
                return
            }
            projectNotExportArray.removeAll()
            var isDirectory: ObjCBool = false
            if FileManager.default.fileExists(atPath: searchFloderPath, isDirectory: &isDirectory), isDirectory.boolValue {
                let enumerator = FileManager.default.enumerator(atPath: searchFloderPath)
                while let file = enumerator?.nextObject() as? String {
                    
                    let filePath = searchFloderPath + "/" + file
                    var isDirectory: ObjCBool = false
                    if FileManager.default.fileExists(atPath: filePath, isDirectory: &isDirectory), isDirectory.boolValue {
                        if file.contains(ignoreFloderArray) {
                            enumerator?.skipDescendants()
                        }
                        continue
                    }
                    if !file.contains(ignoreFileArray) {
                        dealFileContent(filePath, file: file)
                    }
                }
            }else{
                let file = searchFloderPath.components(separatedBy: "/").last!
                dealFileContent(searchFloderPath, file: file)
            }
            Async(.main) { [self] in
                logString += "\n" + "文件查找完成"
                resultOutlineView.reloadData()
            }
        }
    }
}
extension FileCleanVC {
    func obtainPaths() {
        logString += "\n" + "正在获取.xcodeproj路径"
        projectNamePath = File.obtainXcodeProjFilePath(searchFloderPath, isDevelopmentProject: podsProject)
        logString += "\n" + "xcodeproj路径获取成功"
    }
    
    func dealFileContent(_ filePath: String, file: String) {
        if !projectUsedClassFile.contains(filePath) {
            let relativePath = filePath.replacingOccurrences(of: searchFloderPath + "/", with: "")
            projectNotExportArray.append(relativePath)
            var pathArray = relativePath.components(separatedBy: "/")
            if pathArray.count > 0 {
                if pathArray.count == 1 {
                    let model = FileCleanM(isFile: true, name: pathArray.last!, fullPath: filePath)
                    projectNotExportModel.floderList.append(model)
                }else{
                    var currentModel = projectNotExportModel[pathArray.first!]
                    pathArray.removeFirst()
                    while pathArray.count > 1 {
                        currentModel = currentModel[pathArray.first!]
                        pathArray.removeFirst()
                    }
                    let fileModel = FileCleanM(isFile: true, name: pathArray.last!, fullPath: filePath)
                    currentModel.subFloderList.append(fileModel)
                }
            }
            Async(.main) { [self] in
                logString += "\n" + relativePath.components(separatedBy: "/").last! + "未导入工程"
            }
        }
    }
}

extension FileCleanVC: NSOutlineViewDelegate, NSOutlineViewDataSource {
    // 返回视图所需的单元格
    func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
        var cellView = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("DataCell"), owner: self) as? FileCleanV
        if cellView == nil {
            cellView = FileCleanV()
        }
        if let item = item as? FileCleanM {
            cellView?.model = item
        }
        return cellView
    }
    
    // MARK: - NSOutlineViewDataSource
    
    // 返回父项
    func outlineView(_ outlineView: NSOutlineView, parentForItem item: Any) -> Any? {
        if let item = item as? FileCleanM {
            if let index = projectNotExportModel.floderList.firstIndex(where: { $0 === item }) {
                return index >= 0 ? nil : projectNotExportModel.floderList[0]
            }
        }
        return nil
    }
    
    // 返回子项数量
    func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
        if let item = item as? FileCleanM {
            return item.subFloderList.count
        }
        return projectNotExportModel.floderList.count
    }
    
    // 返回指定索引的子项
    func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
        if let item = item as? FileCleanM {
            return item.subFloderList[index]
        }
        return projectNotExportModel.floderList[index]
    }
    
    // 节点是否允许展开
    func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
        let item = item as! FileCleanM
        return item.subFloderList.count > 0
    }
}
